package com.atguigu.eduservice.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.commonutils.ClientEntity.ClientCourse;
import com.atguigu.commonutils.JwtUtils;
import com.atguigu.commonutils.R;
import com.atguigu.eduservice.client.OrderClient;
import com.atguigu.eduservice.client.VodClient;
import com.atguigu.eduservice.entity.EduCourse;
import com.atguigu.eduservice.entity.EduCourseDescription;
import com.atguigu.eduservice.entity.EduSubject;
import com.atguigu.eduservice.entity.EduTeacher;
import com.atguigu.eduservice.entity.chapter.ChapterVo;
import com.atguigu.eduservice.entity.subject.OneSubject;
import com.atguigu.eduservice.entity.subject.TwoSubject;
import com.atguigu.eduservice.entity.vo.*;
import com.atguigu.eduservice.mapper.EduCourseDescriptionMapper;
import com.atguigu.eduservice.mapper.EduCourseMapper;
import com.atguigu.eduservice.mapper.EduSubjectMapper;
import com.atguigu.eduservice.mapper.EduTeacherMapper;
import com.atguigu.eduservice.service.EduChapterService;
import com.atguigu.eduservice.service.EduCourseDescriptionService;
import com.atguigu.eduservice.service.EduCourseService;
import com.atguigu.eduservice.service.EduVideoService;
import com.atguigu.servicebase.exceptionhandler.GuliException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 * 课程 服务实现类
 * </p>
 *
 * @author huangqicai
 * @since 2022-10-21
 */
@Service
public class EduCourseServiceImpl extends ServiceImpl<EduCourseMapper, EduCourse> implements EduCourseService {

    @Autowired
    private EduCourseDescriptionService eduCourseDescriptionService;

    @Autowired
    private EduVideoService eduVideoService;

    @Autowired
    private EduChapterService eduChapterService;

    @Autowired
    private EduCourseDescriptionMapper descriptionMapper;

    @Autowired
    private VodClient vodClient;

    @Autowired
    private EduCourseService eduCourseService;

    @Autowired
    private EduCourseMapper eduCourseMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private EduSubjectMapper subjectMapper;

    @Autowired
    private EduTeacherMapper teacherMapper;

    @Autowired
    private OrderClient orderClient;

    /*根据课程id查询课程基本信息*/
    @Override
    public CourseInfoVo getCourseInfo(String courseId) {
        EduCourse eduCourse = baseMapper.selectById(courseId);
        CourseInfoVo courseInfoVo = new CourseInfoVo();
        BeanUtils.copyProperties(eduCourse,courseInfoVo);
        EduCourseDescription eduCourseDescription = descriptionMapper.selectById(courseId);
        courseInfoVo.setDescription(eduCourseDescription.getDescription());
        return courseInfoVo;
    }

    @Transactional
    /*修改课程基本信息*/
    @Override
    public void updateCourseInfo(CourseInfoVo courseInfoVo) {
        EduCourse eduCourse = new EduCourse();
        BeanUtils.copyProperties(courseInfoVo,eduCourse);
        int update = baseMapper.updateById(eduCourse);
        if(update==0){
            throw new GuliException(20001,"修改课程信息失败");
        }
        EduCourseDescription description = new EduCourseDescription();
        BeanUtils.copyProperties(courseInfoVo,description);
        eduCourseDescriptionService.updateById(description);
    }

    /*课程发布点击下一步执行的方法*/
    @Override
    public CoursePublishVo getPublishCourseInfo(String id) {
        CoursePublishVo publishCourseInfo = eduCourseMapper.getPublishCourseInfo(id);
        return publishCourseInfo;
    }


    /*点击发布课程按钮执行的方法*/
    @Override
    public boolean publishCourse(String id) {
        EduCourse eduCourse = new EduCourse();
        eduCourse.setStatus("Normal");
        QueryWrapper<EduCourse> wrapper = new QueryWrapper<>();
        wrapper.eq("id", id);
        int update = baseMapper.update(eduCourse, wrapper);
        if(update>0){
            return true;
        }
        return false;
    }


    @Transactional
    /*根据课程id删除课程*/
    @Override
    public boolean deleteCourse(String courseId) {

        /*根据课程id查询与该课程有关的视频ids*/
        ArrayList<String> arrayList=eduVideoService.selectVideoIds(courseId);
        if(arrayList.size()>0){
            vodClient.removeAliVideos(arrayList);
        }

        /*根据课程id删除课程里面的小节*/
        boolean flag1=eduVideoService.deleteVideo(courseId);

        /*根据课程id删除课程里面的章节信息*/
        boolean flag2=eduChapterService.deleteChapterByCourseId(courseId);

        /*根据课程id删除课程相关描述信息*/
        boolean flag3=eduCourseDescriptionService.deleteDescriptionByCourseId(courseId);

        /*根据课程id删除课程本身*/
        int delete = baseMapper.deleteById(courseId);

        if(flag1==true && flag2==true && flag3==true && delete>0){
            return true;
        }
        return false;
    }

    /*点击保存比下一步执行的方法*/
    /* courseInfoVo 包含了两个表里面的信息，一个是课程基本信息表edu_course，一个是描述表edu_course_description */
    @Transactional
    @Override
    public R addCourseInfo(CourseInfoVo courseInfoVo) {
        /*1.获取课程基本信息，将课程基本信息添加到数据库*/
        EduCourse eduCourse = new EduCourse();
        BeanUtils.copyProperties(courseInfoVo, eduCourse);
        int insert = baseMapper.insert(eduCourse);
        if(insert==0){
            /*添加课程失败*/
            throw new GuliException(20001,"添加课程信息失败~");
        }
        /*2.获取课程描述信息，将课程描述信息添加到数据库*/
        EduCourseDescription description = new EduCourseDescription();
        BeanUtils.copyProperties(courseInfoVo, description);
        description.setId(eduCourse.getId());
        descriptionMapper.insert(description);
        return R.ok().data("courseId",eduCourse.getId());
    }

    /*条件分页查询课程基本信息*/
    @Override
    public R pageCourse(long current, long limit, CourseQuery courseQuery) {
        QueryWrapper<EduCourse> wrapper = new QueryWrapper<>();
        /*1.解析 courseQuery 得到查询条件 */
        String subjectParentId = courseQuery.getSubjectParentId();
        String subjectId = courseQuery.getSubjectId();
        String teacherId = courseQuery.getTeacherId();
        String title = courseQuery.getTitle();
        /*2.判断然后加入条件查询*/
        if(!subjectParentId.isEmpty()){
            wrapper.eq("subject_parent_id", subjectParentId);
        }
        if(!subjectId.isEmpty()){
            wrapper.eq("subject_id", subjectId);
        }
        if(!teacherId.isEmpty()){
            wrapper.eq("teacher_id", teacherId);
        }
        if(!title.isEmpty()){
            wrapper.eq("title", title);
        }
        /*3.分页查询*/
        Page<EduCourse> page = new Page<EduCourse>(current, limit);
        IPage<EduCourse> res = page(page, wrapper);
        List<EduCourse> records = res.getRecords();
        long total = res.getTotal();
        return R.ok().data("total", total).data("rows", records);
    }

    /*查询8个课程*/
    @Override
    public List<EduCourse> selectCourse() {
        List<EduCourse> courseList=new ArrayList<>();
        /*1.redis里面的key*/
        String redisKey="courseList:";
        String redisValue = stringRedisTemplate.opsForValue().get(redisKey);
        if(StringUtils.isEmpty(redisValue)){
            /*查询数据库*/
            QueryWrapper<EduCourse> wrapper = new QueryWrapper<>();
            wrapper.orderByDesc("id");
            wrapper.last("limit 8");
            courseList = baseMapper.selectList(wrapper);
            if(!StringUtils.isEmpty(courseList)){
                stringRedisTemplate.opsForValue().set(redisKey, JSONObject.toJSONString(courseList));
            }
            return courseList;
        }else {
            List<EduCourse> eduCourses = JSONArray.parseArray(redisValue, EduCourse.class);
            return eduCourses;
        }
    }

    /*前端条件分页查询课程信息*/
    @Override
    public R selectPageCourse(long current, long limit, CourseQueryVo courseQueryVo) {
        QueryWrapper<EduCourse> wrapper = new QueryWrapper<>();
        /*1.先解析数据，为分页查询构造条件*/
        if(!StringUtils.isEmpty(courseQueryVo.getSubjectParentId())){
            wrapper.eq("subject_parent_id", courseQueryVo.getSubjectParentId());
        }
        if(!StringUtils.isEmpty(courseQueryVo.getSubjectId())){
            wrapper.eq("subject_id", courseQueryVo.getSubjectId());
        }
        if(!StringUtils.isEmpty(courseQueryVo.getBuyCountSort())){
            wrapper.orderByDesc("buy_count");
        }
        if(!StringUtils.isEmpty(courseQueryVo.getGmtCreateSort())){
            wrapper.orderByDesc("gmt_create");
        }
        if(!StringUtils.isEmpty(courseQueryVo.getPriceSort())){
            wrapper.orderByDesc("price");
        }
        /*2.分页查询*/
        Page<EduCourse> iPage = (Page<EduCourse>)baseMapper.selectPage(new Page<EduCourse>(current, limit), wrapper);
        /*3.返回信息*/
        HashMap<String, Object> map = new HashMap<>();
        map.put("items",iPage.getRecords());
        map.put("current",iPage.getCurrent());
        map.put("pages",iPage.getPages());
        map.put("size",iPage.getSize());
        map.put("total",iPage.getTotal());
        map.put("hasNext",iPage.hasNext());
        map.put("hasPrevious",iPage.hasPrevious());

        return R.ok().data(map);
    }

    /*前台：获取课程的二级分类*/
    @Override
    public R list2() {
        ArrayList<OneSubject> oneSubjects = new ArrayList<>();
        List<EduSubject> eduSubjects = subjectMapper.selectList(new QueryWrapper<EduSubject>().eq("parent_id", 0));
        for (int i = 0; i < eduSubjects.size(); i++) {
            OneSubject oneSubject=null;
            EduSubject one = eduSubjects.get(i);
            oneSubject = new OneSubject();
            oneSubject.setId(one.getId());
            oneSubject.setTitle(one.getTitle());
            List<EduSubject> twoSubjects = subjectMapper.selectList(new QueryWrapper<EduSubject>().eq("parent_id", one.getId()));
            ArrayList<TwoSubject> twoSubjects1 = new ArrayList<>();
            twoSubjects.stream()
                    .forEach(two->{
                        TwoSubject twoSubject = new TwoSubject();
                        twoSubject.setId(two.getId());
                        twoSubject.setTitle(two.getTitle());
                        twoSubjects1.add(twoSubject);
                    });
            oneSubject.setChildren(twoSubjects1);
            oneSubjects.add(oneSubject);
        }
        return R.ok().data("items",oneSubjects);
    }

    /*前台：根据课程id查询课程的详细信息*/
    @Override
    public R selectCourseVo(String courseId, HttpServletRequest request) {
        /*查询课程相关信息*/
        CourseWebVo courseWebVo=eduCourseMapper.selectCourseVo(courseId);
        /*查询课程的id查询课程的章节小节信息*/
        List<ChapterVo> chapterVoList = eduChapterService.getChapterVideoByCourseId(courseId);
        /*根据当前用户id和课程id判断有没有购买这个课程*/
        String userId = JwtUtils.getMemberIdByJwtToken(request);
        boolean flag = orderClient.isBuyCourse(userId, courseId);
        return R.ok().data("course", courseWebVo).data("chapterVoList", chapterVoList).data("isbuy", flag);
    }

    /*根据课程id获取课程信息*/
    @Override
    public ClientCourse getCourseInfoClient(String courseId) {
        /*1.获取课程信息*/
        EduCourse eduCourse = baseMapper.selectById(courseId);
        ClientCourse clientCourse = new ClientCourse();
        BeanUtils.copyProperties(eduCourse,clientCourse);

        /*2.根据课程id获取老师信息*/
        String teacherId = eduCourse.getTeacherId();
        EduTeacher eduTeacher = teacherMapper.selectById(teacherId);
        clientCourse.setTeacherName(eduTeacher.getName());
        return clientCourse;
    }


}
